/**
 * Copyright 2011 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.google.api.adwords.starterkit;

import com.google.api.adwords.lib.AdWordsUser;
import com.google.api.adwords.starterkit.Synchronizer.AccountSynchronizer;
import com.google.api.adwords.starterkit.settings.CampaignSettings;
import com.google.api.adwords.starterkit.settings.StarterKitSettings;
import com.google.api.adwords.starterkit.wrappers.CampaignWrapper;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.HashMap;

import org.apache.log4j.Logger;

/**
 * The Class StarterKit is the main class of this framework. 
 * Take a look at the demos available at package 
 * <i>com.google.api.adwords.starterkit.examples</i>
 * for a better understanding about how to use the framework.
 * 
 * @author rodrigo.f.vale@gmail.com (Rodrigo Vale)
 */
public class StarterKit {
  private StarterKitSettings starterKitSettings;
  private Connection conn = null;
  private AccountSynchronizer accountSynchronizer;
  private HashMap<String, CampaignWrapper> campaginWrappers;
  private static final Logger log = Logger.getLogger("StarterKit");
  
  /**
   * Instantiates a new StarterKit framework based on the settings file. 
   *
   * @param starterKitSettings the starter kit settings
   */
  public StarterKit(final StarterKitSettings starterKitSettings) {    
    this.starterKitSettings = starterKitSettings;
    campaginWrappers = new HashMap<String, CampaignWrapper>();
    
    try {
      Class.forName("org.sqlite.JDBC");
    } catch (ClassNotFoundException e) {
      System.err.print("Couldn't find SQLite class");
      throw new RuntimeException("Couldn't find SQLite class: org.sqlite.JDBC", 
          e);
    }

    String uri = "jdbc:sqlite:" + starterKitSettings.getDbDir() 
        + starterKitSettings.getDbName() + ".sqlite";
    
    log.debug("Using the Database at: " + uri);
        
    try {
      conn = DriverManager.getConnection(uri);
    } catch (SQLException e) {
      System.err.print("Couldn't connect to " + uri);
      throw new RuntimeException("Couldn't connect to " + uri, e);
    }    
    
    accountSynchronizer = new AccountSynchronizer(starterKitSettings, conn);    
  }
  
  /**
   * Returns the db connection for the local db.
   *
   */
  public Connection getConnection() {
    return conn;
  }
  
  /**
   * Loads campaigns from AdWords Account specified at in the settings.xml
   * file.
   *
   */
  public void load() {
    accountSynchronizer.get(starterKitSettings.getDbSyncType());
  }
  
  /**
   * Gets the campaign wrapper. 
   * In the case of the wrapper doesn't exists, the framework will create a new
   * one using the campaign settings. In the case of the wrapper do exists
   * the framework will return the existing wrapper using the campaigns settings
   * define during the creation of the wrapper.
   *
   * @param campaignName the campaign name
   * @param campaignSettings the campaign settings
   * @return the campaign wrapper
   */
  public CampaignWrapper getCampaignWrapper(String campaignName, 
      CampaignSettings campaignSettings) {
    if (campaginWrappers.containsKey(campaignName)) {
      return campaginWrappers.get(campaignName);
    } else {
      CampaignWrapper campaignWrapper = new CampaignWrapper(campaignName, 
          campaignSettings, conn);
      campaginWrappers.put(campaignName, campaignWrapper);
      return campaignWrapper;
    }    
  }
  
  /**
   * Syncronizes the updates available in local db to AdWords system.
   */
  public void save() {
    accountSynchronizer.put();
  }
  
  /**
   * Finalize starterkit. Makes sure that the db connection will be closed.
   */
  public void done() {    
    try {
      conn.close();
    } catch (SQLException e) {
      System.err.print("Couldn't close DB connection");
      throw new RuntimeException("Couldn't close DB connection", e);
    }
  }
  
  /**
   * Return the AdWordsUser instance. 
   */
  public AdWordsUser getAdWordsUser() {
    return accountSynchronizer.getServiceUtils().getAdWordsUser();
  }

  public static void main(String[] args) {
    System.out.println("StarterKit Verison: " 
        + StarterKitSettings.getVersion());
  }
}
